#include "App_Pool.h"
static char *mq_name = "/App_Pool_mq"; // 队列文件的路径， /代表队列文件所在的目录 /dev/mqueue
static mqd_t mq_fd;                    // 消息队列的描述符   description
static int thread_count;               // 线程的数量
static pthread_t *thread_pool;         // 线程池

static void *pool_thread_receive(void *arg)
{
    // 不断的从消息队列中获取任务并执行
    Task task;
    while (1)
    {
        ssize_t len = mq_receive(mq_fd, (char *)&task, sizeof(Task), NULL);
        if (len == sizeof(Task))
        {
            task.task_fun(task.arg);
        }
    }
}

int App_Pool_Init(int size)
{
    // 1.创建消息队列
    struct mq_attr attr;
    attr.mq_maxmsg = 5;
    attr.mq_msgsize = sizeof(Task);
    mq_fd = mq_open(mq_name, O_CREAT | O_RDWR, 0644, &attr);
    if (mq_fd == -1)
    {
        log_error("创建或者打开消息队列失败");
        return -1;
    }

    // 2.创建线程池
    thread_count = size;
    thread_pool = (pthread_t *)malloc(sizeof(pthread_t) * thread_count);
    for (int i = 0; i < thread_count; i++)
    {
        pthread_create(thread_pool + i, NULL, pool_thread_receive, NULL);
    }

    return 0;
}

void App_Pool_Close(void)
{
    // 1.停止所有线程
    for (int i = 0; i < thread_count; i++)
    {
        // 取消进程
        pthread_cancel(thread_pool[i]);
        // 等待进程结束
        pthread_join(thread_pool[i], NULL);
    }
    // 2.释放内存
    free(thread_pool);

    // 3.关闭并删除消息队列
    mq_close(mq_fd);
    mq_unlink(mq_name);
}

void App_Pool_RegisterTask(int (*task_fun)(void *arg), void *arg)
{
    // 1.创建任务
    Task task = {
        .task_fun = task_fun,
        .arg = arg,
    };

    // 2.将任务发送到消息队列中去
    mq_send(mq_fd, (char *)&task, sizeof(Task), 1);
}
